package com.qing.thread.communication;

/**
 * 线程通信：管程法
 */
public class Monitor {
    public static void main(String[] args) {
        Buffer buffer = new Buffer();

        new Product(buffer).start();
        new Consume(buffer).start();
    }
}

//生产者
class Product extends Thread {
    Buffer buffer;

    public Product(Buffer buffer) {
        this.buffer = buffer;
    }

    //生产者生产产品
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            buffer.push(new Chicken(i));
            System.out.println("KFC生产了：" + i + "只鸡🍗");
        }
    }
}

//消费者
class Consume extends Thread {
    Buffer buffer;

    public Consume(Buffer buffer) {
        this.buffer = buffer;
    }

    //消费者消费产品
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("我吃了：" + buffer.pop().id + "只鸡🍗");
        }
    }
}

//产品
class Chicken {
    //产品编号
    int id;

    public Chicken(int id) {
        this.id = id;
    }
}

//缓冲区
class Buffer {
    //声明一个容器只能存放10个
    Chicken[] chickens = new Chicken[10];
    //计数器
    int count = 0;

    //生产者放入产品
    public synchronized void push(Chicken chicken) {
        if (count == chickens.length) {
            //容器满了，需要通知消费者消费，生产者等待生产
            try {
                //生产者开始等待
                this.wait();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
        //不满10个，就将生产的产品放入容器中
        chickens[count] = chicken;
        count++;
        //通知消费者消费
        //唤醒消费者消费
        this.notify();
    }

    //消费者消费产品
    public synchronized Chicken pop() {
        //如果容器中没有产品，需要通知生产者生产，消费者等待消费
        if (count == 0) {
            //通知消费者生产
            try {
                this.wait();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
        //有产品，则开始消费
        count--;
        Chicken chicken = chickens[count];
        //通知生产者生产产品
        this.notify();
        return chicken;
    }

}